﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using XMLSchemaExtractor.Generator;
namespace XMLSchemaExtractor
{
    public partial class MainWindow : Form
    {
        private const string XMLTAB = "xmlTab";
        private const string DTDTAB = "dtdTab";
        private const string XSDTAB = "xsdTab";
        private const string ORASSTAB = "orassTab";

        private IO io;
        private Controller con;
        private Dictionary<string, string[]> msgs;

        public MainWindow()
        {
            InitializeComponent();
            this.image = new Bitmap(orassDiagPicBox.ClientSize.Width, orassDiagPicBox.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            this.KeyPreview = true;
            this.io = new IO();
            this.con = new Controller();
            this.msgs = new Dictionary<string, string[]>();
        }

        private void browseXmlBtn_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.ShowDialog();
            xmlSrcPathList.Items.Insert(0, ofd.FileName);
            xmlSrcPathList.SelectedIndex = 0;

            if (xmlSrcPathList.SelectedItem.ToString() != "")
            {
                LoadXmlIntoTextBox();
            }
        }

        private void LoadXmlIntoTextBox()
        {
            xmlFileTxt.Text = "";
            if (xmlSrcPathList.SelectedIndex > -1)
            {
                string filePath = xmlSrcPathList.SelectedItem.ToString();

                if (con.IsXmlWellFormed(filePath))
                {
                    ViewXmlFile(filePath);
                    generateAllFilesBtn.Enabled = true;
                    dtdFileTxt.Clear();
                    xsdFileTxt.Clear();
                }
                else
                {
                    var result = MessageBox.Show("XML is not well-formed! Please select a well-formed XML.");
                }
            }
        }

        private void viewXmlBtn_Click(object sender, EventArgs e)
        {
            xmlFileTxt.Text = "";
            if (xmlSrcPathList.SelectedIndex > -1)
            {
                string filePath = xmlSrcPathList.SelectedItem.ToString();

                if (con.IsXmlWellFormed(filePath))
                {
                    ViewXmlFile(filePath);
                    generateAllFilesBtn.Enabled = true;
                }
                else
                {
                    var result = MessageBox.Show("XML is not well-formed! Please select a well-formed XML.");
                }
            }
        }

        private void saveXmlBtn_Click(object sender, EventArgs e)
        {
            SaveFileCommon((Button)sender, this.xmlFileTxt, "Extensible Markup Language|.xml");
        }

        private void saveDtdBtn_Click(object sender, EventArgs e)
        {
            SaveFileCommon((Button)sender, this.dtdFileTxt, "Document Type Definition|.dtd");
        }

        private void saveXsdBtn_Click(object sender, EventArgs e)
        {
            SaveFileCommon((Button)sender, this.xsdFileTxt, "XML Schema Definition|.xsd");
        }

        private void saveOrassBtn_Click(object sender, EventArgs e)
        {
            SaveOrassFile();
        }

        private void clrXmlTxtBtn_Click(object sender, EventArgs e)
        {
            xmlFileTxt.Text = "";
            UpdateStatusMessage("Cleared XML file viewer...");
            clrXmlTxtBtn.Enabled = false;
            saveXmlBtn.Enabled = false;
            generateAllFilesBtn.Enabled = false;
        }

        private void clrDtdTxtBtn_Click(object sender, EventArgs e)
        {
            dtdFileTxt.Text = "";
            UpdateStatusMessage("Cleared DTD file viewer...");
            clrDtdTxtBtn.Enabled = false;
            saveDtdBtn.Enabled = false;
        }

        private void clrXsdTxtBtn_Click(object sender, EventArgs e)
        {
            xsdFileTxt.Text = "";
            UpdateStatusMessage("Cleared XSD file viewer...");
            clrXsdTxtBtn.Enabled = false;
            saveXsdBtn.Enabled = false;
        }

        private void clrOrassDiagBtn_Click(object sender, EventArgs e)
        {
            clrOrass();
            UpdateStatusMessage("Cleared ORA-SS file viewer...");
            clrOrassDiagBtn.Enabled = false;
            saveOrassBtn.Enabled = false;
        }
        private void clrOrass()
        {
            Graphics graphic = Graphics.FromImage(image);
            Pen pen = new Pen(Color.Black, 1);
            graphic.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, image.Width, image.Height));
            Graphics graphic2 = orassDiagPicBox.CreateGraphics();
            graphic2.DrawImageUnscaled(image, 0, 0);
        }
        private void orassDiagPicBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(image, 0, 0, image.Width, image.Height);
        }

        private void mainTabCtrl_DoubleClick(object sender, EventArgs e)
        {
            ShowTab();
        }

        private void mainTabCtrl_Click(object sender, EventArgs e)
        {
            TabPage tab = mainTabCtrl.SelectedTab;
            if (tab.Name.Equals(XMLTAB))
            {
                try
                {
                    msgTxt.Lines = msgs[XMLTAB];
                }
                catch (KeyNotFoundException) { }
                UpdateStatusMessage("Currently viewing XML file...");
            }
            else if (tab.Name.Equals(DTDTAB))
            {
                try
                {
                    msgTxt.Lines = msgs[DTDTAB];
                }
                catch (KeyNotFoundException) { }
                UpdateStatusMessage("Currently viewing DTD file...");
            }
            else if (tab.Name.Equals(XSDTAB))
            {
                try
                {
                    msgTxt.Lines = msgs[XSDTAB];
                }
                catch (KeyNotFoundException) { }
                UpdateStatusMessage("Currently viewing XSD file...");
            }
            else if (tab.Name.Equals(ORASSTAB))
            {
                try
                {
                    msgTxt.Lines = msgs[ORASSTAB];
                }
                catch (KeyNotFoundException) { }
                UpdateStatusMessage("Currently viewing ORA-SS file...");
            }
        }

        private void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F5)
            {
                ShowTab();
            }
            else if (e.Control && e.KeyCode == Keys.S)
            {
                SaveTab();
            }
        }

        private void xmlFileTxt_TextChanged(object sender, EventArgs e)
        {
            if (!xmlFileTxt.Text.Equals(""))
            {
                saveXmlBtn.Enabled = true;
                clrXmlTxtBtn.Enabled = false;
            }
            else
            {
                saveXmlBtn.Enabled = false;
                clrXmlTxtBtn.Enabled = false;
            }
        }

        private void dtdFileTxt_TextChanged(object sender, EventArgs e)
        {
            if (!dtdFileTxt.Text.Equals(""))
            {
                saveDtdBtn.Enabled = true;
            }
            else
            {
                saveDtdBtn.Enabled = false;
                clrDtdTxtBtn.Enabled = false;
            }
        }

        private void xsdFileTxt_TextChanged(object sender, EventArgs e)
        {
            if (!xsdFileTxt.Text.Equals(""))
            {
                saveXsdBtn.Enabled = true;
            }
            else
            {
                saveXsdBtn.Enabled = false;
                clrXsdTxtBtn.Enabled = false;
            }
        }

        private void maxCurTabMenuItem_Click(object sender, EventArgs e)
        {
            ShowTab();
        }

        private void saveCurTabMenuItem_Click(object sender, EventArgs e)
        {
            SaveTab();
        }

        private void generateAllFilesBtn_Click(object sender, EventArgs e)
        {
            if (!xmlFileTxt.Text.Equals(""))
            {
                string filePath = xmlSrcPathList.SelectedItem.ToString();
                GenerateDtdFile(filePath);
                GenerateXsdFile(filePath);
                GenerateOrassFile(filePath);
                UpdateStatusMessage("Generated DTD, XSD and ORA-SS files...");
                msgTxt.Lines = msgs[mainTabCtrl.SelectedTab.Name];
            }
        }

        private void clrMsgBoxBtn_Click(object sender, EventArgs e)
        {
            msgTxt.Text = "";
        }

        private void ViewXmlFile(string filePath)
        {
            string[] msg;
            xmlFileTxt.Lines = con.GetXML(filePath, out msg);
            msgs[XMLTAB] = msg;
        }

        private void GenerateDtdFile(string filePath)
        {
            string[] msg;
            dtdFileTxt.Lines = con.GenerateDTD(filePath, (int)numericMinEnumInstances.Value, (int)numericMaxEnumValues.Value, (int)numericMinEnumRatio.Value, (int)numericMinFixed.Value, (int)numericMinId.Value, out msg);
            msgs[DTDTAB] = msg;
            clrDtdTxtBtn.Enabled = true;
            saveDtdBtn.Enabled = true;
        }

        private void GenerateXsdFile(string filePath)
        {
            string[] msg;
            xsdFileTxt.Lines = con.GenerateXSD(filePath, out msg);
            msgs[XSDTAB] = msg;
            clrXsdTxtBtn.Enabled = true;
            saveXsdBtn.Enabled = true;
        }

        private void GenerateOrassFile(string filePath)
        {
            clrOrass();
            string[] msg;
            Graphics graphic = Graphics.FromImage(image);
            SolidBrush brush = new SolidBrush(Color.Black);
            graphic.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, image.Width, image.Height));
            con.GenerateORASS(filePath, graphic, out msg);
            orassDiagPicBox.Refresh();
            msgs[ORASSTAB] = msg;
            clrOrassDiagBtn.Enabled = true;
            saveOrassBtn.Enabled = true;
        }

        private void SaveFileCommon(Button sender, TextBox listBox, string filter)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = filter;
            DialogResult result = sfd.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                string filename = sfd.FileName;
                if (!filename.Equals(""))
                {
                    io.WriteToFile(filename, listBox.Lines);
                    UpdateStatusMessage("File saved in " + filename + " successfully...");
                }
                if (sender.Name.Equals("saveXmlBtn")) saveXmlBtn.Enabled = false;
                else if (sender.Name.Equals("saveDtdBtn")) saveDtdBtn.Enabled = false;
                else if (sender.Name.Equals("saveXsdBtn")) saveXsdBtn.Enabled = false;
            }
        }

        private void SaveOrassFile()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Bitmap|*.bmp|JPEG|*.jpg|PNG|*.png";
            DialogResult result = sfd.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                string filename = sfd.FileName;
                if (!filename.Equals(""))
                {
                    string[] tokens = filename.Split('.');
                    string ext = tokens[tokens.Length - 1];
                    switch (ext)
                    {
                        case "bmp":
                            image.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                            break;
                        case "jpg":
                            image.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                            break;
                        case "png":
                            image.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Png);
                            break;
                        default:
                            image.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                            break;
                    }
                    UpdateStatusMessage("Diagram saved in " + filename + " successfully...");
                }
                saveOrassBtn.Enabled = false;
            }
        }

        private void SaveTab()
        {
            TabPage tab = mainTabCtrl.SelectedTab;
            if (tab.Name.Equals(XMLTAB))
            {
                if (saveXmlBtn.Enabled)
                {
                    SaveFileCommon(this.saveXmlBtn, this.xmlFileTxt, "Extensible Markup Language|.xml");
                }
            }
            else if (tab.Name.Equals(DTDTAB))
            {
                if (saveDtdBtn.Enabled)
                {
                    SaveFileCommon(this.saveDtdBtn, this.dtdFileTxt, "Document Type Definition|.dtd");
                }
            }
            else if (tab.Name.Equals(XSDTAB))
            {
                if (saveXsdBtn.Enabled)
                {
                    SaveFileCommon(this.saveXsdBtn, this.xsdFileTxt, "XML Schema Definition|.xsd");
                }
            }
            else if (tab.Name.Equals(ORASSTAB))
            {
                if (saveOrassBtn.Enabled)
                {
                    SaveOrassFile();
                }
            }
        }

        private void ShowTab()
        {
            TabPage tab = mainTabCtrl.SelectedTab;
            if (tab.Name.Equals(XMLTAB))
            {
                TextWindow txtWin = new TextWindow(xmlFileTxt.Lines, "XML");
                txtWin.Show();
            }
            else if (tab.Name.Equals(DTDTAB))
            {
                TextWindow txtWin = new TextWindow(dtdFileTxt.Lines, "DTD");
                txtWin.Show();
            }
            else if (tab.Name.Equals(XSDTAB))
            {
                TextWindow txtWin = new TextWindow(xsdFileTxt.Lines, "XSD");
                txtWin.Show();
            }
            else if (tab.Name.Equals(ORASSTAB))
            {

            }
        }

        private void UpdateStatusMessage(string msg)
        {
            statusMsg.Text = msg;
        }

        private void buttonReload_Click(object sender, EventArgs e)
        {
            LoadXmlIntoTextBox();
        }
    }
}
